home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / language / embedded / m68k / cc68k.arc / STMT.C < prev    next >
C/C++ Source or Header  |  1986-10-26  |  13KB  |  423 lines

  1. #include        "stdio.h"
  2. #include        "c.h"
  3. #include        "expr.h"
  4. #include        "gen.h"
  5. #include        "cglbdec.h"
  6.  
  7.  
  8. /*
  9.  *    68000 C compiler
  10.  *
  11.  *    Copyright 1984, 1985, 1986 Matthew Brandt.
  12.  *  all commercial rights reserved.
  13.  *
  14.  *    This compiler is intended as an instructive tool for personal use. Any
  15.  *    use for profit without the written consent of the author is prohibited.
  16.  *
  17.  *    This compiler may be distributed freely for non-commercial use as long
  18.  *    as this notice stays intact. Please forward any enhancements or questions
  19.  *    to:
  20.  *
  21.  *        Matthew Brandt
  22.  *        Box 920337
  23.  *        Norcross, Ga 30092
  24.  */
  25.  
  26. /*
  27.  *      the statement module handles all of the possible c statements
  28.  *      and builds a parse tree of the statements.
  29.  *
  30.  *      each routine returns a pointer to a statement parse node which
  31.  *      reflects the statement just parsed.
  32.  */
  33.  
  34. struct snode    *statement();   /* forward declaration */
  35.  
  36. struct snode    *whilestmt()
  37. /*
  38.  *      whilestmt parses the c while statement.
  39.  */
  40. {       struct snode    *snp;
  41.         snp =(struct snode *) xalloc(sizeof(struct snode));
  42.         snp->stype = st_while;
  43.         getsym();
  44.         if( lastst != openpa )
  45.                 error(ERR_EXPREXPECT);
  46.         else    {
  47.                 getsym();
  48.                 if( expression(&(snp->exp)) == 0 )
  49.                         error(ERR_EXPREXPECT);
  50.                 needpunc( closepa );
  51.                 snp->s1 = statement();
  52.                 }
  53.         return snp;
  54. }
  55.  
  56. struct snode    *dostmt()
  57. /*
  58.  *      dostmt parses the c do-while construct.
  59.  */
  60. {       struct snode    *snp;
  61.         snp =(struct snode *) xalloc(sizeof(struct snode));
  62.         snp->stype = st_do;
  63.         getsym();
  64.         snp->s1 = statement();
  65.         if( lastst != kw_while )
  66.                 error(ERR_WHILEXPECT);
  67.         else    {
  68.                 getsym();
  69.                 if( lastst != openpa )
  70.                         error(ERR_EXPREXPECT);
  71.                 else    {
  72.                         getsym();
  73.                         if( expression(&(snp->exp)) == 0 )
  74.                                 error(ERR_EXPREXPECT);
  75.                         needpunc(closepa);
  76.                         }
  77.                 if( lastst != end )
  78.                         needpunc( semicolon );
  79.                 }
  80.         return snp;
  81. }
  82.  
  83. struct snode    *forstmt()
  84. {       struct snode    *snp;
  85.         snp =(struct snode *) xalloc(sizeof(struct snode));
  86.         getsym();
  87.         needpunc(openpa);
  88.         if( expression(&((struct enode *)(snp->label))) == 0 )
  89.                 snp->label = 0;
  90.         needpunc(semicolon);
  91.         snp->stype = st_for;
  92.         if( expression(&(snp->exp)) == 0 )
  93.                 snp->exp = 0;
  94.         needpunc(semicolon);
  95.         if( expression(&((struct enode *)(snp->s2))) == 0 )
  96.                 snp->s2 = 0;
  97.         needpunc(closepa);
  98.         snp->s1 = statement();
  99.         return snp;
  100. }
  101.  
  102. struct snode    *ifstmt()
  103. /*
  104.  *      ifstmt parses the c if statement and an else clause if
  105.  *      one is present.
  106.  */
  107. {       struct snode    *snp;
  108.         snp =(struct snode *) xalloc(sizeof(struct snode));
  109.         snp->stype = st_if;
  110.         getsym();
  111.         if( lastst != openpa )
  112.                 error(ERR_EXPREXPECT);
  113.         else    {
  114.                 getsym();
  115.                 if( expression(&(snp->exp)) == 0 )
  116.                         error(ERR_EXPREXPECT);
  117.                 needpunc( closepa );
  118.                 snp->s1 = statement();
  119.                 if( lastst == kw_else ) {
  120.                         getsym();
  121.                         snp->s2 = statement();
  122.                         }
  123.                 else
  124.                         snp->s2 = 0;
  125.                 }
  126.         return snp;
  127. }
  128.  
  129. struct snode    *casestmt()
  130. /*
  131.  *      cases are returned as seperate statements. for normal
  132.  *      cases label is the case value and s2 is zero. for the
  133.  *      default case s2 is nonzero.
  134.  */
  135. {       struct snode    *snp;
  136.         struct snode    *head, *tail;
  137.         snp =(struct snode *) xalloc(sizeof(struct snode));
  138.         if( lastst == kw_case ) {
  139.                 getsym();
  140.                 snp->s2 = 0;
  141.                 snp->stype = st_case;
  142.                 snp->label =(int *) intexpr();
  143.                 }
  144.         else if( lastst == kw_default) {
  145.                 getsym();
  146.                 snp->s2 =(struct snode *) 1;
  147.                 }
  148.         else    {
  149.                 error(ERR_NOCASE);
  150.                 return 0;
  151.                 }
  152.         needpunc(colon);
  153.         head = 0;
  154.         while( lastst != end &&
  155.                 lastst != kw_case &&
  156.                 lastst != kw_default ) {
  157.                 if( head == 0 )
  158.                         head = tail = statement();
  159.                 else    {
  160.                         tail->next = statement();
  161.                         if( tail->next != 0 )
  162.                                 tail = tail->next;
  163.                         }
  164.                 tail->next = 0;
  165.                 }
  166.         snp->s1 = head;
  167.         return snp;
  168. }
  169.  
  170. int     checkcases(head)
  171. /*
  172.  *      checkcases will check to see if any duplicate cases
  173.  *      exist in the case list pointed to by head.
  174.  */
  175. struct snode    *head;
  176. {
  177.     struct snode    *top, *cur;
  178.     cur = top = head;
  179.     while( top != 0 )
  180.     {
  181.         cur = top->next;
  182.         while( cur != 0 )
  183.         {
  184.             if( (!(cur->s1 || cur->s2) && cur->label == top->label)
  185.                 || (cur->s2 && top->s2) )
  186.             {
  187.                 printf(" duplicate case label %d\n",cur->label);
  188.                 return 1;
  189.             }
  190.             cur = cur->next;
  191.         }
  192.         top = top->next;
  193.     }
  194.     return 0;
  195. }
  196.  
  197. struct snode    *switchstmt()
  198. {       struct snode    *snp;
  199.         struct snode    *head, *tail;
  200.         snp =(struct snode *) xalloc(sizeof(struct snode));
  201.         snp->stype = st_switch;
  202.         getsym();
  203.         needpunc(openpa);
  204.         if( expression(&(snp->exp)) == 0 )
  205.                 error(ERR_EXPREXPECT);
  206.         needpunc(closepa);
  207.         needpunc(begin);
  208.         head = 0;
  209.         while( lastst != end ) {
  210.                 if( head == 0 )
  211.                         head = tail = casestmt();
  212.                 else    {
  213.                         tail->next = casestmt();
  214.                         if( tail->next != 0 )
  215.                                 tail = tail->next;
  216.                         }
  217.                 tail->next = 0;
  218.                 }
  219.         snp->s1 = head;
  220.         getsym();
  221.         if( checkcases(head) )
  222.                 error(ERR_DUPCASE);
  223.         return snp;
  224. }
  225.  
  226. struct snode    *retstmt()
  227. {       struct snode    *snp;
  228.         snp =(struct snode *) xalloc(sizeof(struct snode));
  229.         snp->stype = st_return;
  230.         getsym();
  231.         expression(&(snp->exp));
  232.         if( lastst != end )
  233.                 needpunc( semicolon );
  234.         return snp;
  235. }
  236.  
  237. struct snode    *breakstmt()
  238. {       struct snode    *snp;
  239.         snp =(struct snode *) xalloc(sizeof(struct snode));
  240.         snp->stype = st_break;
  241.         getsym();
  242.         if( lastst != end )
  243.                 needpunc( semicolon );
  244.         return snp;
  245. }
  246.  
  247. struct snode    *contstmt()
  248. {       struct snode    *snp;
  249.         snp =(struct snode *) xalloc(sizeof(struct snode));
  250.         snp->stype = st_continue;
  251.         getsym();
  252.         if( lastst != end )
  253.                 needpunc( semicolon );
  254.         return snp;
  255. }
  256.  
  257. struct snode    *exprstmt()
  258. /*
  259.  *      exprstmt is called whenever a statement does not begin
  260.  *      with a keyword. the statement should be an expression.
  261.  */
  262. {       struct snode    *snp;
  263.         snp =(struct snode *) xalloc(sizeof(struct snode));
  264.         snp->stype = st_expr;
  265.         if( expression(&(snp->exp)) == 0 ) {
  266.                 error(ERR_EXPREXPECT);
  267.                 getsym();
  268.                 }
  269.         if( lastst != end )
  270.                 needpunc( semicolon );
  271.         return snp;
  272. }
  273.  
  274. struct snode    *compound()
  275. /*
  276.  *      compound processes a block of statements and forms a linked
  277.  *      list of the statements within the block.
  278.  *
  279.  *      compound expects the input pointer to already be past the
  280.  *      begin symbol of the block.
  281.  */
  282. {       struct snode    *head, *tail;
  283.         head = 0;
  284.         while( lastst != end ) {
  285.                 if( head == 0 )
  286.                         head = tail = statement();
  287.                 else    {
  288.                         tail->next = statement();
  289.                         if( tail->next != 0 )
  290.                                 tail = tail->next;
  291.                         }
  292.                 }
  293.         getsym();
  294.         return head;
  295. }
  296.  
  297. struct snode    *labelstmt()
  298. /*
  299.  *      labelstmt processes a label that appears before a
  300.  *      statement as a seperate statement.
  301.  */
  302. {       struct snode    *snp;
  303.         SYM             *sp;
  304.         snp =(struct snode *) xalloc(sizeof(struct snode));
  305.         snp->stype = st_label;
  306.         if( (sp =(SYM *) search(lastid,lsyms.head)) == 0 ) {
  307.                 sp =(SYM *) xalloc(sizeof(SYM));
  308.                 sp->name =(char *) litlate(lastid);
  309.                 sp->storage_class = sc_label;
  310.                 sp->tp = 0;
  311.                 sp->value.i =(long) nextlabel++;
  312.                 insert(sp,&lsyms);
  313.                 }
  314.         else    {
  315.                 if( sp->storage_class != sc_ulabel )
  316.                         error(ERR_LABEL);
  317.                 else
  318.                         sp->storage_class = sc_label;
  319.                 }
  320.         getsym();       /* get past id */
  321.         needpunc(colon);
  322.         if( sp->storage_class == sc_label ) {
  323.                 snp->label =(int *) sp->value.i;
  324.                 snp->next = 0;
  325.                 return snp;
  326.                 }
  327.         return 0;
  328. }
  329.  
  330. struct snode    *gotostmt()
  331. /*
  332.  *      gotostmt processes the goto statement and puts undefined
  333.  *      labels into the symbol table.
  334.  */
  335. {       struct snode    *snp;
  336.         SYM             *sp;
  337.         getsym();
  338.         if( lastst != id ) {
  339.                 error(ERR_IDEXPECT);
  340.                 return 0;
  341.                 }
  342.         snp =(struct snode *) xalloc(sizeof(struct snode));
  343.         if( (sp =(SYM *) search(lastid,lsyms.head)) == 0 ) {
  344.                 sp =(SYM *) xalloc(sizeof(SYM));
  345.                 sp->name =(char *) litlate(lastid);
  346.                 sp->value.i =(long) nextlabel++;
  347.                 sp->storage_class = sc_ulabel;
  348.                 sp->tp = 0;
  349.                 insert(sp,&lsyms);
  350.                 }
  351.         getsym();       /* get past label name */
  352.         if( lastst != end )
  353.                 needpunc( semicolon );
  354.         if( sp->storage_class != sc_label && sp->storage_class != sc_ulabel)
  355.                 error( ERR_LABEL );
  356.         else    {
  357.                 snp->stype = st_goto;
  358.                 snp->label =(int *) sp->value.i;
  359.                 snp->next = 0;
  360.                 return snp;
  361.                 }
  362.         return 0;
  363. }
  364.  
  365. struct snode    *statement()
  366. /*
  367.  *      statement figures out which of the statement processors
  368.  *      should be called and transfers control to the proper
  369.  *      routine.
  370.  */
  371. {       struct snode    *snp;
  372.         switch( lastst ) {
  373.                 case semicolon:
  374.                         getsym();
  375.                         snp = 0;
  376.                         break;
  377.                 case begin:
  378.                         getsym();
  379.                         snp = compound();
  380.                         return snp;
  381.                 case kw_if:
  382.                         snp = ifstmt();
  383.                         break;
  384.                 case kw_while:
  385.                         snp = whilestmt();
  386.                         break;
  387.                 case kw_for:
  388.                         snp = forstmt();
  389.                         break;
  390.                 case kw_return:
  391.                         snp = retstmt();
  392.                         break;
  393.                 case kw_break:
  394.                         snp = breakstmt();
  395.                         break;
  396.                 case kw_goto:
  397.                         snp = gotostmt();
  398.                         break;
  399.                 case kw_continue:
  400.                         snp = contstmt();
  401.                         break;
  402.                 case kw_do:
  403.                         snp = dostmt();
  404.                         break;
  405.                 case kw_switch:
  406.                         snp = switchstmt();
  407.                         break;
  408.                 case id:
  409.                         while( isspace(lastch) )
  410.                                 getch();
  411.                         if( lastch == ':' )
  412.                                 return labelstmt();
  413.                         /* else fall through to process expression */
  414.                 default:
  415.                         snp = exprstmt();
  416.                         break;
  417.                 }
  418.         if( snp != 0 )
  419.                 snp->next = 0;
  420.         return snp;
  421. }
  422.  
  423.